// middleware/request_log.go
package middleware

import (
	"bytes"
	"context"
	"encoding/json"
	"gin-zc/util"
	"time"

	"github.com/gin-gonic/gin"
	"go.uber.org/zap"
)

// RequestLogMiddleware 记录请求/响应日志到文件，关联log_id
func RequestLogMiddleware() gin.HandlerFunc {
	return func(c *gin.Context) {
		// 1. 生成log_id并传递
		logID := util.GenerateLogID()
		c.Set("log_id", logID) // 存入Gin上下文

		// 存入request context（供SQL日志使用）
		ctx := context.WithValue(c.Request.Context(), "log_id", logID)
		c.Request = c.Request.WithContext(ctx)
		// 2. 拦截响应数据（替换默认ResponseWriter）
		wrapper := &ResponseWriter{
			ResponseWriter: c.Writer,
			body:           &bytes.Buffer{},
		}
		c.Writer = wrapper

		// 3. 提取请求参数（并脱敏）
		requestParams := util.ParseRequestParams(c)
		paramsJSON, _ := json.Marshal(requestParams) // 转为JSON字符串便于日志记录
		// 2. 记录请求开始（写入app.log）
		startTime := time.Now()
		req := c.Request
		util.AppLogger.Info(
			"request_start",
			zap.String("log_id", logID),
			zap.String("method", req.Method),
			zap.String("path", req.URL.Path),
			zap.String("query", req.URL.RawQuery),
			zap.String("remote_ip", c.ClientIP()),
			zap.String("user_agent", req.UserAgent()),
			zap.String("start_time", startTime.Format("2006-01-02 15:04:05.000")),
			zap.String("params", string(paramsJSON)), // 记录脱敏后的请求参数
		)

		// 3. 处理请求
		c.Next()

		// 4. 记录请求结束（写入app.log）
		responseBody := wrapper.GetBody()

		endTime := time.Now()
		util.AppLogger.Info(
			"request_end",
			zap.String("log_id", logID),
			zap.Int("status", c.Writer.Status()),
			zap.Duration("cost_ms", endTime.Sub(startTime)),
			zap.Int("resp_size", c.Writer.Size()),
			zap.String("end_time", endTime.Format("2006-01-02 15:04:05.000")),
			zap.String("response", responseBody), // 记录脱敏后的响应数据
		)
	}
}
